﻿using System;
using System.IO;
using System.Net;
using System.Text;
using Azure.Online.Proxy.Server;

namespace Azure.Online.Proxy.Actions {
    public class ProxyActionResult : ActionResult {
        private readonly HttpWebResponse _response;

        public ProxyActionResult(HttpWebResponse response) {
            _response = response;
        }

        public bool AcceptBase64 { get; set; }

        public override void Execute(HttpServerContext context) {
            var response = context.Response;
            response.StatusCode = (int)_response.StatusCode;
            response.StatusDescription = _response.StatusDescription;
            RegisterHeaders(response);

            var stream = _response.GetResponseStream();
            if (AcceptBase64) {
                var mem = new MemoryStream();
                stream.CopyTo(mem);
                var bytes = mem.ToArray();
                var content = Convert.ToBase64String(bytes);
                var output = Encoding.UTF8.GetBytes(content);
                response.Headers["Content-Length"] = output.Length.ToString();
                response.OutputStream.Write(output, 0, output.Length);
            } else {
                if (_response.ContentLength >= 0) {
                    response.ContentLength = _response.ContentLength;
                }
                try {
                    if (response.ContentLength.HasValue) {
                        StreamUtils.CopyStream(stream, response.OutputStream);
                    }
                } catch (Exception) {
                }
            }

            context.Response.OutputStream.Flush();
            context.Response.OutputStream.Close();
        }

        protected virtual void RegisterHeaders(HttpServerResponse response) {
            response.ContentType = _response.ContentType;
            foreach (string headerName in _response.Headers.Keys) {
                switch (headerName) {
                    case "Transfer-Encoding":
                        CopyTransferEncoding(response);
                        break;
                    case "Content-Type":
                        response.ContentType = _response.Headers[headerName];
                        break;
                    case "Date":
                        response.Headers["Date"] = _response.Headers[headerName];
                        break;
                    default:
                        if (headerName.StartsWith("x-ms-")) {
                            CopyHeader(response, headerName);
                        }
                        break;
                }
            }
        }

        private void CopyTransferEncoding(HttpServerResponse response) {
            string value = _response.Headers["Transfer-Encoding"];
            switch (value) {
                case "chunked":
                    response.SendChunked = true;
                    break;
            }
        }

        private void CopyHeader(HttpServerResponse response, string headerName) {
            var value = _response.Headers[headerName];
            if (!string.IsNullOrEmpty(value)) {
                response.Headers[headerName] = value;
            }
        }

    }
}